
  //#include "../evolution.h" 
  #include "../experiment.h"
  #include "gelimits.h"
  #include "grammar.h"
  
  
  #define NULL_NODE  (Node *) NULL
  /* Rappresenta il valore nullo per i puntatori agli oggetti della
     classe Node.
  */
  #define NULL_NODE_PTR (Node **) NULL
  /* Rappresenta il valore nullo per i puntatori dei puntatori agli og-
     getti della classe Node.
  */


  /************************************************************************

   Definizione delle classi: POPULATION, INDIVIDUAL, NODE, EVOLUTION,
                             COPY, CROSSOVER, MUTATION.

  ************************************************************************/


  class ge_Individual;
//  class Tree;
 // class Node;
  /* Dichiarazione delle classi utilizzate successivamente nel file.
  */
  
   /*
  +++++++++++++++++++++++++++ classe NODE +++++++++++++++++++++++++++++++++
  *** Definita il: 
  Gli oggetti di questa classe sono i singoli nodi che costituiscono gli
  individui della popolazione e contengono dei simboli.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */
  class Node
  {
  public:
     Node(char ch);
     /* E' la procedura costruttrice della classe ed � di tipo ricorsivo.
        Genera un nodo al quale assegna come simbolo quello passato come
        parametro dopo, se il simbolo passato � un non terminale, chiede
        all'oggetto della classe grammatica l'applicazione della relativa
        regola e genera un numero di figli pari al numero di caratteri del-
        la stringa ottenuta chiamando la procedura in maniera ricorsiva.
     */
     Node(char ch, int not_choose);
     /* E' la stessa procedura definita al punto precedente. L'unica diffe-
        renza � che accetta un parametro in pi�, il quale specifica quale
        clausola (chunk) NON bisogna scegliere tra quelle della regola re-
        lativa al simbolo specificato dal parametro ch.
     */
     Node();
     /* E' una seconda procedura costruttrice della classe ed � utilizzata
        per costruire le copie degli alberi di derivazione degli individui.
        E' anch'essa di tipo ricorsivo.
     */
     Node *build_copy();
     /* Costruisce una copia del nodo cui appartiene  e di tutta la sua
        parte sottostante in maniera ricorsiva richiamando se stessa. */

     void del_node();
     /* E' la procedura che restituisce il nodo alla memoria, � di tipo ri-
        corsivo in quanto restituisce alla memoria  prima i nodi figli e poi
        se stesso. In pratica, per distruggere un albero di derivazione ba-
        sta chiamare questa procedura sul suo nodo radice.
     */
     void del_Node(Node *good_node_ptr);
     /* E' l'altra  procedura distruttiva della classe, da utilizzare quan-
        do non si vuole distruggere l'intero albero ma solo una parte di
        esso.
     */
  protected:
     char symbol;
     /* E' il simbolo contenuto nel nodo.
     */
     int N_sons;
     /* E' il numero di figli posseduti dal nodo.
     */
     int clause_num;
     /* Specifica il numero della clausola (chunk) utilizzato da questo no-
        do per continuare la costruzione dell'albero.
     */
     Node *sons[MAX_SONS];
     /* E' un array di puntatori ai nodi figli del nodo.
     */
     Node *next_free;
     /* E' un puntatore usata dall'allocatore di memoria per gli elementi
        di questa classe e serve a gestire la lista dei nodi liberi, quelli
        cio� non allocati. */
     Node **find_not_term (int &N);
     /* Questa procedura estrae un simbolo non terminale tra quelli presen-
        ti nell'individuo scegliendolo in maniera casuale. Questa procedura
        restituisce il puntatore al puntatore al nodo che contiene il sim-
        bolo trovato e il simbolo. Questa procedura � usata per implementa-
        re l'operazione di crossover e quella di mutazione.
     */
     void add_not_terms(char symbol, int &next_free);
     /* Questa procedura � ricorsiva ed � chiamata  dalla  procedura
        extract_symbol. Controlla se symbol � contenuto in uno dei nodi fi-
        gli del nodo, se s� esso viene memorizzato nell'array che si trova
        negli oggetti della classe crossover e si incrementa di uno il va-
        lore del parametro next_free che punta al prossimo elemento libero
        del suddtto array. Dopo tale controllo, se il nodo possiede figli
        la procedura viene chiamata in maniera ricorsiva su tutti i figli
        del nodo.
     */
      int visit_node(char* &string_ptr, int &av_chars);
     /* E'una procedura ricorsiva che serve a scrivere il fenotipo dell'al-
        bero e a calcolore la profondita' dell'albero e il numero di nodi
	    contenuto. Il primo parametro e' un puntatore alla stringa dove sc
        rivere il fenotipo, il secondo, invece, indica il numero di carat-
        teri ancora disponibile nella stringa.     
     */
     int comp_nodes();
     /* Calcola, in maniera ricorsiva, il numero di nodi dell'albero sotto-
        stante compreso se stesso. */
     void print_nodes(int depth);
     /* Stampa a video tutti i nodi della profondit� specificata, come pa-
        rametro.
     */
     Node *find_second_symbol(int depth);
     /* Trova il nodo che contiene lo stesso simbolo di quello di partenza
        e che si trova alla profondita' (sempre rispetto al nodo di parten-
        za) specificata dal parametro.
     */
     Node **find_deepest_symbol(char ch);
     /* Questa procedura serve a trovare il puntatore del puntatore del no-
        do piu' profondo che si trova al di sotto del nodo e che contiene
        il simbolo passato come parametro. Questa procedura serve ad imple-
        mentare la nuova versione della mutazione.
     */
     int comp_depth();
     /* E' la procedura ricorsiva per il calcolo della prfondita' massima
        un albero.
     */
     void mutation(float prob);
     /* E' la procedura di mutazione di tipo ricorsivo utilizzata per otte-
        nere piu' mutazioni dell'albero di derivazione. 
     */

  friend class Tree;
  friend class Cross_tree;
  friend class Cross_list;
  friend class ge_Mutation;
  };




   /*
  +++++++++++++++++++++++++++ classe Tree +++++++++++++++++++++++++++++++++
  *** Definita il: 
  Gli oggetti di questa classe sono i gli alberi di derivazione degli in-
  dividui.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */
  class Tree
  {
  public:
     Tree();
     /* E' la costruttrice della classe, effettua alcune inizzializzaizoni.
     */
     Tree(char symbol);
     /* E' la seconda procedura costruttrice di classe e costruisce l'albe-
        ro di derivazione con simbolo di start uguale a symbol.
     */
     Tree(const Tree &right_tree);
     /* E' un'altra costruttrice della classe, e' il costruttore di copie 
        utilizzato nella costruzione di copie di liste di alberi.
     */
     void del_tree();
     /* E' la procedura che restituisce alla memoria gli oggetti della cla-
        sse Node, chiamandola procedura del_Node sul suo nodo radice.
     */
     Tree operator=(const Tree &right_tree);
     /* E' l'oveloading dell'operatore di assegnamento.
     */
     bool operator<(const Tree &right_tree);
     /* E' l'operatore di confronto.
     */
     void print_tree();
     /* Stampa l'albero di derivazione a terminale.
     */
     void give_string(char* &string, int &av_chars);
     /* Scrive la stringa contenuta nell'albero nella stgringa passata come
        parametro. Il secondo parametro rappresenta il numero di caratteri 
        possono essere ancora scritti nella stringa.  
     */
     inline int give_N_nodes(){return N_nodes;}
     /* Restituisice il numero di nodi dell'albero
     */
     int comp_N_nodes();
     /* Restituisice il numero di nodi dell'albero
     */
     int give_label(){ return label;}
     /* Restituisce la label dell'albero (data mining)
     */
     void set_label(int l){label = l;}
     /* Setta la label dell'albero
     */ 
     
     

  protected: 
     int N_nodes;
     /* E' il numero totale di nodi di cui � costituito l'albero.
     */
     int label;
     /* È la label dell'albero: per data mining.      
      */
     Node *root;
     /* E' il puntatore al nodo radice dell'albero di generazione rappre-
        sentato dall'individuo.
     */
     Node **choose_not_term();
     /* Questa  procedura sceglie in maniera casuale un nodo dell'individuo
        e restituisce come risultato un puntatore al puntatore del nodo
        scelto, il quale si trova nel nodo padre del nodo scelto.
     */
     Node **extract_symbol (char symbol);
     /* Questa procedura sceglie in maniera casuale uno dei nodi dell'indi-
        viduo che contiene il simbolo dato come input e restituisce il pun-
        tatore ad esso. Anche questa procedura � utilizzata per implementa-
        re l'operazione di crossover.
     */


     friend class ge_Individual;
     friend class Cross_tree;
     friend class Cross_list;
     friend class ge_Mutation;
  };


  /*
  +++++++++++++++++++++++++++ classe GE_Individual ++++++++++++++++++++++++
  *** Definita il: 
  Gli oggetti di questa classe sono i singoli individui della popolazione e
  sono degli alberi di generazione di espressioni ottenuti applicando le
  regole della grammatica.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */
  class ge_Individual : public Individual
  {
  public:

     ge_Individual();
     /* E' la procedura costruttrice della classe ed e' utilizzata quando
        bisogna costruire la copia di un individuo gi� esistente.  Essa
        costruisce solo un oggetto della classe ge_Individual, senza cos-
        truire l'albero di derivazione.
     */
     void build_list();
     /* Costruisce la  lista di alberi dell'individuo e ne scrive il feno-
        tipo.
     */
     void build_list(int a, int b);
     /* Costruisce la  lista di alberi dell'individuo, i parametri a e b
      * definiscono rispettivamente la lunghezza minima e massima della lista.
     */
     char phenotype[MAX_CHAR_PHENOTYPE];
     /* E' la stringa che contiene il fenotipo codificato dall'individuo.
     
     virtual void update();
     /* Aggiorna  tutti gli attribuiti, dopo che l'individuo e' stato modi-
        ficato dagli aoperatori genetici, chiamando le funzioni che effet-
        tuano i relativi calcoli. Il primo parametro e' il data set da
        clusterizzare e il secondo il numero di items. Questi parametri
        servono per il ricalcolo della fitness.
     */
     void write_pheno();
     /* Scrive il fenotipo dell'individuo chiamando la procedura che visita
        l'albero.
     */ 
     int comp_nodes_num();
     /* Calcola il numero di nodi presenti nell'albero. 
     */
     void kill();
     /* E' la procedura specifica della classe per cancellare gli individui
        di questa classe.
     */

  protected:
     list<class Tree> trees_list;
     /* E' la lista degli alberi di derivazione. 
     */
     int nodes_num;
     /* E' il numero di nodi presenti nell'albero dell'individuo.
     */

     friend class ge_Population;
     friend class Cross_tree;
     friend class Cross_list;
     friend class ge_Mutation;
  };




 

  /*
  +++++++++++++++++++++++++++ classe CROSS_TREE +++++++++++++++++++++++++++
  *** Definita il: 
  Questa classe implementa l'operatore di crossover eseguita al livello di 
  alberi e contiene tutte le procedure necessarie a implementare tale ope-
  razione.
  *** Ultima modifica:
  */

  class Cross_tree : public Crossover
  {
  public:
     Cross_tree();
     /* E' la procedura costruttrice della classe (� vuota).
     */
     Cross_tree(float prob_value);
     /* E' la seconda costruttrice della classe. Il parametro rappresenta
        la probabilita' di applicazioen dell'operatore.
     */
     void apply(Individual *input_ptr_1, Individual *input_ptr_2,
                Individual* &output_ptr_1, Individual* &output_ptr_2);
     /* Applica l'operazione di crossover alla coppia di individui in in-
        gresso (input_ptr_1 e input_ptr_2), creandone due copie e applican-
        dovi l'operazione di crossover. Le due copie cos� modificate vengo-
        no restituite nella seconda coppia di parametri in ingresso
        (output_ptr_1 e output_ptr_2).
     */
     void cross(Tree &tree_1, Tree &tree_2);
     /* Applica il crossover ai due alberi passati come parametri.
     */
     void ini_nodes_ptr_ptr();
     /* Inizializza un astruttura un'array utilizzato per per implementare
        il crossover.
     */

  friend class Node;
  friend class ge_Individual;
  };
 
  
   /*
  +++++++++++++++++++++++++++ classe CROSS_list +++++++++++++++++++++++++++
  *** Definita il: 
  Questa classe implementa l'operatore di crossover eseguita al livello di 
  liste e contiene tutte le procedure necessarie a implementare tale ope-
  razione.
  *** Ultima modifica:
  */

  class Cross_list : public Crossover
  {
  public:
     Cross_list();
     /* E' la procedura costruttrice della classe (� vuota).
     */
     Cross_list(float prob_value);
     /* E' la seconda costruttrice della classe. Il parametro rappresenta
        la probabilita' di applicazioen dell'operatore.
     */
     Cross_list(float prob_value, bool s);
     /* E' la terza costruttrice della classe. I parametri rappresentano:
      * -- probabilita' di applicazioen dell'operatore.
      * -- crossover ordinato
     */
     void apply(Individual *input_ptr_1, Individual *input_ptr_2,
                Individual* &output_ptr_1, Individual* &output_ptr_2);
     /* Applica l'operazione di crossover alla coppia di individui in in-
        gresso (input_ptr_1 e input_ptr_2), creandone due copie e applican-
        dovi l'operazione di crossover. Le due copie cos� modificate vengo-
        no restituite nella seconda coppia di parametri in ingresso
        (output_ptr_1 e output_ptr_2).
     
     virtual void apply2(Individual *input_ptr_1, Individual *input_ptr_2,
                Individual* &output_ptr_1, Individual* &output_ptr_2);
     /* Applica l'operazione di crossover alla coppia di individui in in-
        gresso (input_ptr_1 e input_ptr_2), creandone due copie e applican-
        dovi l'operazione di crossover. Le due copie cos� modificate vengo-
        no restituite nella seconda coppia di parametri in ingresso
        (output_ptr_1 e output_ptr_2).
        IMPORTANTE! Quest'operatore � di tipo nuovo ed � euristico. Esso si 
        basa sul concetto di clusters all' interno dell'individuo. 
     */
     void cross(list<class Tree> &list_1, list<class Tree> &list_2);
     /* Applica il crossover alle due liste di alberi passati come  come 
        parametri.
     */
     void set_stat(){stat = true;}
  private:
     bool sorting;
     /* Specifica se effettuare il sorting prima del crossover.
     */
     bool stat;
     /* Specifica se il crossover è quello statico (non modifica la lunghezza).
     */

  friend class Node;
  friend class ge_Individual;
  };
 


  /*
  +++++++++++++++++++++++++++ Classe MUTATION +++++++++++++++++++++++++++++
  *** Definita il: 
  Questa classe implementa l'operatore di mutazione e contiene tutte le
  procedure necessarie a implementare tale operazione.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */

  class ge_Mutation : public Mutation
  {
  public:
    ge_Mutation();
    /* E' la procedura costruttrice della classe (� vuota).
    */
    ge_Mutation(float prob_value);
    /* E' la seconda costruttrice della classe, inizializza il valore di
       probabilita' di applicazione della mutazione.
    
     void apply(Individual *input_ptr, Individual* &output_ptr);
     /* Applica l'operazione di mutazione all'individuo puntato dal primo
        parametro in ingresso (input_ptr), creandone una copia e applican-
        dovi l'operazione di mutazione. La copia cos� modificata viene res-
        tiuita nel secondo parametro (output_ptr).
     */
     void apply(Individual* &input_ptr);
     /* E' uguale alla precedente, tranne che per il fatto che NON costrui-
        sce la copia, ma muta direttamente l'individuo passato come parame-
        tro.
     */
     void mut(Tree &tree_input);
     /* Applica la mutazione all' albero passato come parametro.
     */
  };
  

